#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>

/**
 * 计算不大于 sqrt(y) 的最大整数 a（对应 Java 的 getA 方法）
 * @param y: 输入正整数
 * @return: 满足 a² < y 的最大整数 a
 */
static int getA(int y) {
    int i = 0;
    while (i * i < y) {
        i++;
    }
    return i - 1;
}

/**
 * 迭代法求解平方根（对应 Java 的 sqrt 方法）
 * @param y: 输入正整数（y ≥ 1）
 * @return: 平方根结果；若输入非法，设置 errno 并返回 NAN
 */
double sqrt_custom(int y) {
    // 输入校验：y < 1 时返回错误
    if (y < 1) {
        fprintf(stderr, "错误：请输入正整数\n");
        errno = EINVAL;  // 设置错误码标识非法参数
        return NAN;      // 返回非数值表示错误
    }

    int a = getA(y);
    int numerator = y - a * a;
    double x = 1.0;

    // 迭代收敛循环：精度控制 1e-15
    while (1) {
        double newX = (double)numerator / (2 * a + x);
        // 判断收敛条件：两次迭代值的绝对误差小于 1e-15
        if (fabs(newX - x) < 1e-15) {
            break;
        }
        x = newX;
    }

    return a + x;
}

int main() {
    // 测试：计算 14 的平方根
    int target = 14;
    double result = sqrt_custom(target);

    // 检查是否计算出错
    if (isnan(result)) {
        return EXIT_FAILURE;
    }

    // 输出结果并对比标准库 sqrt 函数
    printf("自定义方法计算结果：%.15f\n", result);
    double std_result = sqrt(target);
    printf("标准库 sqrt 结果：%.15f\n", std_result);
    printf("是否相等：%s\n", (fabs(result - std_result) < 1e-15) ? "true" : "false");

    return EXIT_SUCCESS;
}